﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
/// <summary>
/// Project逻辑代码【生成CopyToRuntime代码】
/// </summary>
public partial class ESF_Logic
{
    #region BuildAutoCode 生成AutoCode
    /// <summary>
    /// 自动生成代码
    /// </summary>
    /// <returns>true:成功,false:失败</returns>
    [ESF_OneKeyBuild(ESF_enOneKeyBuildStep.BuildAutoCode)]
    public static bool BuildAutoCode()
    {
        bool result = true;        
        BuildAssetImproteCode();
        BuildTagEnumCode();
        BuildAttributeUseEnumConstCode();
        BuildCopyToX();
        return result;
    }
    #endregion

    #region BuildCopyToX 生成BuildCopyToX代码
    /// <summary>
    /// 生成BuildCopyToX
    /// </summary>
    [ESF_ProjectQuickButton("{0} {1}", ESF_enGUIDisplayWord.Build, ESF_enGUIDisplayWord.CopyToX)]
    public static void BuildCopyToX()
    {
        if (projectSetting.xml.copyToXs != null)
        {
            foreach (var key in projectSetting.xml.copyToXs)
            {
                ESF_Utility.CopyCSharpToX(key.srcFolder, key.targetFolder, key.classify.ToString(), (code) => { return code.ReplaceSignESF2HF(); }, (path) => { return path.ReplaceSignESF2HF(); });
            }
            ESF_Utility.ExecuteMenuAssetsRefresh();
            EditorUtility.ClearProgressBar();
        }        
        ESF_P.ESF_Log($"BuildCopyToRuntimeCode Success.");
    }
    #endregion

    #region BuildAssetImproteCode 生成BuildAssetImprote代码
    /// <summary>
    /// 生成BuildAssetImprote代码
    /// </summary>
    [ESF_ProjectQuickButton("{0} AssetImporter {1}", ESF_enGUIDisplayWord.Build, ESF_enGUIDisplayWord.ExtendsCode)]
    public static void BuildAssetImproteCode()
    {
        ESF_BuildTextAsset bta = new ESF_BuildTextAsset("ESF_AssetImporterExtend", projectSetting.xml.editorExtendFolder, enESF_UnityFileExt.CS, "");
        string code = File.ReadAllText(ESF_enResxTempleteFile.Compiler_AssetImporterExtend_Script_txt);        
        Type type = typeof(AssetImporter);        
        List<Type> types = ESF_Utility.GetTypes((t) => { return t.ESF_IsTypeOrSubTypeOfNotAbstract(type) && !t.HasObsoleteAttribute(); });
        List<string> nameSpaces = new List<string>();
        Dictionary<string, Type> destTypes = new Dictionary<string, Type>();
        foreach (var key in types)
        {
            if (!nameSpaces.Contains(key.Namespace))
            {
                nameSpaces.Add(key.Namespace);
            }
            if (!destTypes.ContainsKey(key.FullName))
            {
                destTypes.Add(key.FullName, key);
            }
        }
        code = code.CompilerCSharp(new {
            types = new List<Type>(destTypes.Values),
            nameSpaces
        });
        bta.SetText(code);
        bta.CreateAsset();
        ESF_Utility.ExecuteMenuAssetsRefresh();
        ESF_P.ESF_Log($"BuildAssetImproteCode Success.");
    }
    #endregion

    #region BuildTagEnumCode 生成BuildTagEnumCode
    /// <summary>
    /// 生成BuildTagEnumCode代码
    /// </summary>
    [ESF_ProjectQuickButton("{0} {1}", ESF_enGUIDisplayWord.Build, ESF_enGUIDisplayWord.TagEnumCode)]
    public static void BuildTagEnumCode()
    {
        UnityEngine.Object obj = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0];
        SerializedObject so = new SerializedObject(obj);
        SerializedProperty tags = so.FindProperty("tags");
        SerializedProperty m_SortingLayers = so.FindProperty("m_SortingLayers");
        SerializedProperty layers = so.FindProperty("layers");
        
        Dictionary<string, string> tagNames = new Dictionary<string, string>();
        int tagCount = tags.arraySize;
        if (InternalEditorUtility.tags != null)
        {
            foreach (var key in InternalEditorUtility.tags)
            {
                if (!string.IsNullOrEmpty(key) && !tagNames.ContainsKey(key))
                {
                    tagNames.Add(key, key.ESF_OnlyCNUAndOtherReplaceU());
                }
            }
        }
        for (int i = 0; i < tagCount; i++)
        {
            SerializedProperty t = tags.GetArrayElementAtIndex(i);
            if (!string.IsNullOrEmpty(t.stringValue) && !tagNames.ContainsKey(t.stringValue))
            {
                tagNames.Add(t.stringValue, t.stringValue.ESF_OnlyCNUAndOtherReplaceU());
            }
        }

        int layerCount = layers.arraySize;
        Dictionary<string, string> layerNames = new Dictionary<string, string>();
        if (InternalEditorUtility.layers != null)
        {
            foreach (var key in InternalEditorUtility.layers)
            {
                if (!string.IsNullOrEmpty(key) && !layerNames.ContainsKey(key))
                {
                    layerNames.Add(key, key.ESF_OnlyCNUAndOtherReplaceU());
                }
            }
        }

        for (int i = 0; i < layerCount; i++)
        {
            SerializedProperty t = layers.GetArrayElementAtIndex(i);
            if (!string.IsNullOrEmpty(t.stringValue) && !layerNames.ContainsKey(t.stringValue))
            {
                layerNames.Add(t.stringValue, t.stringValue.ESF_OnlyCNUAndOtherReplaceU());
            }
        }

        int sortLayerCount = m_SortingLayers.arraySize;
        Dictionary<string, string> sortingLayerNames = new Dictionary<string, string>();
        for (int i = 0; i < sortLayerCount; i++)
        {
            SerializedProperty t = m_SortingLayers.GetArrayElementAtIndex(i);
            if (!string.IsNullOrEmpty(t.displayName) && !sortingLayerNames.ContainsKey(t.displayName))
            {
                sortingLayerNames.Add(t.displayName, t.displayName.ESF_OnlyCNUAndOtherReplaceU());
            }
        }

        string folder = projectSetting.xml.GetCopyToX_UtilityFolder(ESF_enCopyToX.CopyToHF);
        ESF_BuildTextAsset bta = new ESF_BuildTextAsset("ESF_GlobalUtility_TagAndLayer", folder, enESF_UnityFileExt.CS, "");
        string code = File.ReadAllText(ESF_enResxTempleteFile.Compiler_TagAndLayerScript_txt);
        code = code.CompilerCSharp(new
        {
            tags = tagNames,
            sortingLayers = sortingLayerNames,
            layers = layerNames,
        });
        bta.SetText(code);
        bta.CreateAsset();
        ESF_Utility.ExecuteMenuAssetsRefresh();
        ESF_P.ESF_Log($"BuildTagEnumCode Success.");
    }
    #endregion

    #region BuildAttributeUseEnumConstCode 生成属性使用的枚举常量代码
    /// <summary>
    /// 生成属性使用的枚举常量代码
    /// </summary>
    [ESF_ProjectQuickButton("{0} {1}", ESF_enGUIDisplayWord.Build, ESF_enGUIDisplayWord.AttributeUseEnumConstCode)]
    public static void BuildAttributeUseEnumConstCode()
    {
        string folder = projectSetting.xml.GetCopyToX_UtilityFolder(ESF_enCopyToX.CopyToHF);
        ESF_BuildTextAsset bta = new ESF_BuildTextAsset("ESF_GlobalUtility_AttributeUseEnumConst", folder, enESF_UnityFileExt.CS, "");
        string code = File.ReadAllText(ESF_enResxTempleteFile.Compiler_AttributeUseEnumConstCode_txt);

        Dictionary<string, int> renderMode = typeof(RenderMode).ESF_NameToValue();
        Dictionary<string, int> threadPriority = typeof(ThreadPriority).ESF_NameToValue();        
        code = code.CompilerCSharp(new
        {
            renderModes = renderMode,
            threadPriorities = threadPriority,
        });
        bta.SetText(code);
        bta.CreateAsset();
        ESF_Utility.ExecuteMenuAssetsRefresh();
        ESF_P.ESF_Log($"BuildAttributeUseEnumConstCode Success.");        
    }
    #endregion

    #region ExtractCode
    /// <summary>
    /// 导出代码
    /// </summary>
    public static void ExtractCode()
    {
        if (extractCode.xml.items != null)
        {
            foreach (var key in extractCode.xml.items)
            {
                ESF_Utility.CopyCSharpToX(key.srcFolder, key.targetFolder, $"ExtractCode=>{key.replaceSign}",
                    (code) => { 
                        return code.ReplaceExtractSign2X(key.replaceSign); 
                    },
                    (path) => { 
                        return path.ReplaceExtractSign2X(key.replaceSign);
                    });
            }
            ESF_Utility.ExecuteMenuAssetsRefresh();
            EditorUtility.ClearProgressBar();
        }
        ESF_P.ESF_Log($"ExtractCode Success.");
    }
    #endregion
}
#endif